Skip to content

OSAC-240: Add describe networkclass CLI command and update #701

Open
SiddarthR56 wants to merge 1 commit into
osac-project:mainfrom
SiddarthR56:osac-240
Open

OSAC-240: Add describe networkclass CLI command and update #701
SiddarthR56 wants to merge 1 commit into
osac-project:mainfrom
SiddarthR56:osac-240

Conversation

@SiddarthR56

@SiddarthR56 SiddarthR56 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add describe networkclass CLI subcommand with tabwriter output showing all NetworkClass fields (ID, name, title, description, capabilities, default, state, message)
  • Update get networkclass table YAML to include description and per-capability (IPv4/IPv6/Dual-Stack) columns alongside existing ID, name, title, and default columns
  • Register networkclass in the describe command tree with alias networkclasses and add corresponding test coverage (8 rendering tests + parent registration tests)

Summary by CodeRabbit

  • New Features
    • Added CLI command to describe network classes by ID or name
    • Enhanced network class display with additional columns showing description and IP capability details (IPv4, IPv6, dual stack support)

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds a describe networkclass CLI subcommand backed by a gRPC NetworkClassesClient lookup. Includes a RenderNetworkClass formatter with tabwriter output and enum-prefix stripping, extended list-table YAML columns (DESCRIPTION, IPV4, IPV6, DUAL STACK), and wiring into the parent describe command with Ginkgo tests.

Changes

Describe NetworkClass Command

Layer / File(s) Summary
Cobra command, runner, and renderer
internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go
Defines Cmd() with usage, aliases, and argument arity; implements runnerContext.run for gRPC-based lookup via NetworkClassesClient and lookup.Find; adds boolYesNo helper; implements RenderNetworkClass with tabwriter, "-" fallbacks, enum-prefix stripping, and capability yes/no rendering; adds shortHelp/longHelp constants with shell examples.
Parent describe wiring and list table columns
internal/cmd/cli/describe/describe_cmd.go, internal/rendering/tables/osac.public.v1.NetworkClass.yaml
Registers networkclass.Cmd() as a subcommand of describe; adds DESCRIPTION, IPV4, IPV6, and DUAL STACK columns to the NetworkClass list table YAML with conditional value expressions.
Tests
internal/cmd/cli/describe/networkclass/describe_networkclass_suite_test.go, internal/cmd/cli/describe/networkclass/describe_networkclass_test.go, internal/cmd/cli/describe/describe_cmd_test.go
Adds Ginkgo suite entrypoint; tests RenderNetworkClass across nil status, unset capabilities, prefix stripping, yes/no booleans, and default - placeholders; updates parent describe tests to assert networkclass alias and subcommand presence.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • osac-project/fulfillment-service#391: Adds virtualnetwork, subnet, and securitygroup describe subcommands using the same pattern of registering via result.AddCommand in describe_cmd.go.

Suggested reviewers

  • larsks
  • tzvatot
  • trewest

Poem

A network class steps into the light,
describe networkclass — the CLI shines bright.
Tab-writer aligns, yes/no fills the screen,
Enum prefixes stripped, the output stays clean.
🌐 gRPC calls, Ginkgo tests in a row —
Another subcommand, ready to go! 🚀

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title references OSAC-240 and mentions 'Add describe networkclass CLI command' which directly matches the primary change of introducing a new describe networkclass subcommand, though it's incomplete with trailing 'and update'. Complete the title by specifying what is being updated (e.g., 'OSAC-240: Add describe networkclass CLI command and update get networkclass table') to fully convey the scope of changes.
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed Comprehensive search across all PR files (describe commands, tests, YAML config) found no hardcoded secrets, API keys, tokens, passwords, base64 strings >32 chars, URLs with credentials, or suspici...
No-Weak-Crypto ✅ Passed The PR adds CLI describe subcommand for NetworkClass and updates its table schema. No cryptographic functions (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or non-const...
No-Injection-Vectors ✅ Passed No injection vectors detected. User input safely escaped in CEL filter via fmt.Sprintf %q; output rendering uses proto data only; YAML expressions reference message fields without user input embedd...
Container-Privileges ✅ Passed PR adds CLI command code and a data rendering YAML template—not container/K8s manifests. No privileged settings, hostPID, hostNetwork, hostIPC, SYS_ADMIN, or allowPrivilegeEscalation keywords present.
No-Sensitive-Data-In-Logs ✅ Passed No sensitive data logging found. The code assigns a logger but never uses it, and the ref user input is never logged. Output is only written to console via tabwriter for display purposes.
Ai-Attribution ✅ Passed AI tool use (Cursor/Claude) is properly attributed with "Assisted-by" trailer in the commit message, following Red Hat's attribution guidelines correctly.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci-robot

openshift-ci-robot commented Jun 15, 2026

Copy link
Copy Markdown

@SiddarthR56: This pull request references OSAC-240 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add describe networkclass CLI subcommand with tabwriter output showing all NetworkClass fields (ID, name, title, description, capabilities, default, state, message)
  • Update get networkclass table YAML to include description and per-capability (IPv4/IPv6/Dual-Stack) columns alongside existing ID, name, title, and default columns
  • Register networkclass in the describe command tree with alias networkclasses and add corresponding test coverage (8 rendering tests + parent registration tests)

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci

openshift-ci Bot commented Jun 15, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: SiddarthR56
Once this PR has been reviewed and has the lgtm label, please assign jhernand for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Comment thread internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go Outdated
@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown

@SiddarthR56: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-vmaas f70a23f link true /test e2e-vmaas

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

…with description/capabilities columns

Assisted-by: Cursor/Claude

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go`:
- Around line 87-89: The RenderNetworkClass function currently ignores errors
from fmt.Fprintf and Flush operations, violating Go error handling guidelines.
Modify RenderNetworkClass to return an error type, check and propagate errors
from all write operations (fmt.Fprintf and Flush calls within the function
body), and then at the call site where RenderNetworkClass is invoked, capture
and return the error instead of returning nil unconditionally.
- Around line 73-80: The client.List call in the anonymous function passed to
lookup.Find does not have a timeout constraint on the context, which can cause
the command to hang indefinitely if the backend stalls. Before passing ctx to
client.List, wrap it with context.WithTimeout to establish a bounded deadline
for the RPC call, ensuring the operation fails gracefully if it exceeds the
timeout duration rather than hanging indefinitely.

In `@internal/rendering/tables/osac.public.v1.NetworkClass.yaml`:
- Around line 29-35: The capability columns for IPV4 (line 29), IPV6 (line 32),
and DUAL STACK (line 35) use two-way ternary expressions that conflate missing
capabilities with false values, rendering both as 'no'. Update each of these
three value expressions to be three-way conditionals: return 'yes' when the
capability exists and is true, return '-' when capabilities are missing or the
specific capability field doesn't exist, and return 'no' when the capability
explicitly exists but is false. This aligns with how other optional fields are
handled in this table (as referenced in line 38).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 868f8f63-0c1b-4f86-9d51-c97b80121f9e

📥 Commits

Reviewing files that changed from the base of the PR and between e5f93c5 and aacf3d3.

📒 Files selected for processing (6)
  • internal/cmd/cli/describe/describe_cmd.go
  • internal/cmd/cli/describe/describe_cmd_test.go
  • internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go
  • internal/cmd/cli/describe/networkclass/describe_networkclass_suite_test.go
  • internal/cmd/cli/describe/networkclass/describe_networkclass_test.go
  • internal/rendering/tables/osac.public.v1.NetworkClass.yaml

Comment on lines +73 to +80
matched, err := lookup.Find(ref, "network class", func(filter string, limit int32) ([]*publicv1.NetworkClass, error) {
resp, err := client.List(ctx, publicv1.NetworkClassesListRequest_builder{
Filter: proto.String(filter),
Limit: proto.Int32(limit),
}.Build())
if err != nil {
return nil, fmt.Errorf("failed to describe network class: %w", err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "describe_networkclass_cmd.go" -type f | head -20

Repository: osac-project/fulfillment-service

Length of output: 146


🏁 Script executed:

wc -l internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go

Repository: osac-project/fulfillment-service

Length of output: 148


🏁 Script executed:

cat -n internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go

Repository: osac-project/fulfillment-service

Length of output: 5855


Add an RPC deadline for the List call.

Line 74 passes ctx directly to client.List() without a timeout. If the backend stalls, this command can hang indefinitely. Wrap the List call with a bounded timeout context.

Proposed fix
 import (
+	"context"
 	"fmt"
 	"io"
 	"log/slog"
 	"strings"
 	"text/tabwriter"
+	"time"
@@
 	matched, err := lookup.Find(ref, "network class", func(filter string, limit int32) ([]*publicv1.NetworkClass, error) {
-		resp, err := client.List(ctx, publicv1.NetworkClassesListRequest_builder{
+		listCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
+		defer cancel()
+		resp, err := client.List(listCtx, publicv1.NetworkClassesListRequest_builder{
 			Filter: proto.String(filter),
 			Limit:  proto.Int32(limit),
 		}.Build())

Per Go guidelines, all gRPC calls must use context.Context with cancellation and timeouts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go` around
lines 73 - 80, The client.List call in the anonymous function passed to
lookup.Find does not have a timeout constraint on the context, which can cause
the command to hang indefinitely if the backend stalls. Before passing ctx to
client.List, wrap it with context.WithTimeout to establish a bounded deadline
for the RPC call, ensuring the operation fails gracefully if it exceeds the
timeout duration rather than hanging indefinitely.

Source: Coding guidelines

Comment on lines +87 to +89
RenderNetworkClass(c.console, matched)

return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, find and examine the target file
fd "describe_networkclass_cmd.go" -type f

Repository: osac-project/fulfillment-service

Length of output: 247


🏁 Script executed:

# Read the file to verify the code and error handling
cat -n internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go

Repository: osac-project/fulfillment-service

Length of output: 5855


🏁 Script executed:

# Search for other render functions that might have the same pattern
rg "func Render" --type go -A 5 internal/cmd/cli/describe/

Repository: osac-project/fulfillment-service

Length of output: 3657


🏁 Script executed:

# Check other render functions to see if they also ignore errors
rg "func Render" -A 50 internal/cmd/cli/describe/ | grep -E "(func Render|fmt.Fprintf|Flush)" | head -40

Repository: osac-project/fulfillment-service

Length of output: 4598


🏁 Script executed:

# Check one of the other render functions more closely to confirm pattern
sed -n '100,160p' internal/cmd/cli/describe/virtualnetwork/describe_virtualnetwork_cmd.go | head -70

Repository: osac-project/fulfillment-service

Length of output: 1274


🏁 Script executed:

# Check how the other render functions are called to see if they also ignore errors
rg "Render(VirtualNetwork|Subnet|SecurityGroup|PublicIP|NetworkClass)" internal/cmd/cli/describe/ -B 2 -A 2

Repository: osac-project/fulfillment-service

Length of output: 8615


Make RenderNetworkClass return an error and propagate it to the caller.

Lines 141–151 ignore all fmt.Fprintf and Flush errors, silently losing output failures (e.g., broken pipe). Change RenderNetworkClass to return an error, check each write operation, and propagate errors at line 87.

Proposed fix
-func RenderNetworkClass(w io.Writer, nc *publicv1.NetworkClass) {
+func RenderNetworkClass(w io.Writer, nc *publicv1.NetworkClass) error {
 	writer := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
@@
-	fmt.Fprintf(writer, "ID:\t%s\n", nc.GetId())
-	fmt.Fprintf(writer, "Name:\t%s\n", name)
-	fmt.Fprintf(writer, "Title:\t%s\n", title)
-	fmt.Fprintf(writer, "Description:\t%s\n", description)
-	fmt.Fprintf(writer, "Supports IPv4:\t%s\n", supportsIPv4)
-	fmt.Fprintf(writer, "Supports IPv6:\t%s\n", supportsIPv6)
-	fmt.Fprintf(writer, "Supports Dual Stack:\t%s\n", supportsDualStack)
-	fmt.Fprintf(writer, "Default:\t%s\n", isDefault)
-	fmt.Fprintf(writer, "State:\t%s\n", state)
-	fmt.Fprintf(writer, "Message:\t%s\n", message)
-	writer.Flush()
+	if _, err := fmt.Fprintf(writer, "ID:\t%s\n", nc.GetId()); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Name:\t%s\n", name); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Title:\t%s\n", title); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Description:\t%s\n", description); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Supports IPv4:\t%s\n", supportsIPv4); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Supports IPv6:\t%s\n", supportsIPv6); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Supports Dual Stack:\t%s\n", supportsDualStack); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Default:\t%s\n", isDefault); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "State:\t%s\n", state); err != nil { return err }
+	if _, err := fmt.Fprintf(writer, "Message:\t%s\n", message); err != nil { return err }
+	if err := writer.Flush(); err != nil { return err }
+	return nil
 }
@@
-	RenderNetworkClass(c.console, matched)
+	if err := RenderNetworkClass(c.console, matched); err != nil {
+		return fmt.Errorf("failed to render network class: %w", err)
+	}

Violates the Go guideline: never ignore error returns.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/cmd/cli/describe/networkclass/describe_networkclass_cmd.go` around
lines 87 - 89, The RenderNetworkClass function currently ignores errors from
fmt.Fprintf and Flush operations, violating Go error handling guidelines. Modify
RenderNetworkClass to return an error type, check and propagate errors from all
write operations (fmt.Fprintf and Flush calls within the function body), and
then at the call site where RenderNetworkClass is invoked, capture and return
the error instead of returning nil unconditionally.

Source: Coding guidelines

Comment on lines +29 to +35
value: "has(this.capabilities) && this.capabilities.supports_ipv4? 'yes': 'no'"

- header: IPV6
value: "has(this.capabilities) && this.capabilities.supports_ipv6? 'yes': 'no'"

- header: DUAL STACK
value: "has(this.capabilities) && this.capabilities.supports_dual_stack? 'yes': 'no'"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find and examine the NetworkClass YAML file
find . -name "*NetworkClass*.yaml" -type f

Repository: osac-project/fulfillment-service

Length of output: 199


🏁 Script executed:

# Check the actual content of the file at the specified lines
cat -n internal/rendering/tables/osac.public.v1.NetworkClass.yaml | sed -n '20,40p'

Repository: osac-project/fulfillment-service

Length of output: 774


🏁 Script executed:

# Search for the renderer mentioned in the scratchpad
find . -path "*/internal/cmd/cli/describe/networkclass/*describe_networkclass_cmd.go" -type f

Repository: osac-project/fulfillment-service

Length of output: 146


🏁 Script executed:

# Check if there's any CEL-related logic or tests that validate these expressions
rg "supports_ipv4|supports_ipv6|supports_dual_stack" -A 2 -B 2

Repository: osac-project/fulfillment-service

Length of output: 12260


Fix capability columns to distinguish missing vs. false values.

Lines 29, 32, 35 currently conflate absent capabilities with explicit false, rendering both as 'no'. Use a three-way expression to return '-' when capabilities are missing, consistent with other optional fields in this table (see line 38).

Proposed fix
 - header: IPV4
-  value: "has(this.capabilities) && this.capabilities.supports_ipv4? 'yes': 'no'"
+  value: "has(this.capabilities)? (this.capabilities.supports_ipv4? 'yes': 'no'): '-'"

 - header: IPV6
-  value: "has(this.capabilities) && this.capabilities.supports_ipv6? 'yes': 'no'"
+  value: "has(this.capabilities)? (this.capabilities.supports_ipv6? 'yes': 'no'): '-'"

 - header: DUAL STACK
-  value: "has(this.capabilities) && this.capabilities.supports_dual_stack? 'yes': 'no'"
+  value: "has(this.capabilities)? (this.capabilities.supports_dual_stack? 'yes': 'no'): '-'"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/rendering/tables/osac.public.v1.NetworkClass.yaml` around lines 29 -
35, The capability columns for IPV4 (line 29), IPV6 (line 32), and DUAL STACK
(line 35) use two-way ternary expressions that conflate missing capabilities
with false values, rendering both as 'no'. Update each of these three value
expressions to be three-way conditionals: return 'yes' when the capability
exists and is true, return '-' when capabilities are missing or the specific
capability field doesn't exist, and return 'no' when the capability explicitly
exists but is false. This aligns with how other optional fields are handled in
this table (as referenced in line 38).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants